﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace JTParcrelHelper.MessageClient
{
    public class MessageReceiveTask : ServiceTaskAdapter
    {
        public const String TASK_NAME = "ClientReceiveTask";
        private String taskName = TASK_NAME;
        private MessageProClient myStation;

        public MessageReceiveTask(MessageProClient _station)
        {
            myStation = _station;
        }

        public override int PreparedTask()
        {
            return 0;
        }

        public override void ExecuteTask()
        {
            string strmthd = "JsonAccessClientReceiveTask.ExecuteTask";

            try
            {
                if (myStation.IsNetArrived == false)
                {
                    //Logger.LogInfo("JsonAccessClientReceiveTask", "【MessageClient】： Net cannot arrived.");
                    Thread.Sleep(2000);
                    return;
                }

                if (!myStation.IsSocketConnect())
                {
                    //Logger.LogError("JsonAccessClientReceiveTask", "【MessageClient】： Server:Socket disconnect ，cannot receive from server.");
                    Thread.Sleep(5000);
                    return;
                }

                ////////////////////////////////////////////////

                Socket sckClient = myStation.ClientSocket;
                string sEndPoint = sckClient.RemoteEndPoint.ToString();

                byte[] bFrameLen = new byte[MessageProClient.FRAME_LENGTH];
                byte[] contentBuffer = new byte[MessageProClient.MAX_FRAME_LENGTH];
                bool isFinished = false;
                int iFrameLen = 0;

                while (!isFinished)
                {
                    int len = sckClient.Receive(bFrameLen, MessageProClient.FRAME_LENGTH, SocketFlags.None);

                    if (len < 1)
                    {
                        if (sckClient != null && sckClient.Connected)
                        {
                            //Logger.LogInfo(strmthd, "【MessageClient】： Server【" + sEndPoint + "】disconnect now.");
                            sckClient.Close();
                            myStation.TriggerStationDisconnectEvent(this, new EargsClientDisconnect());
                        }
                        return;
                    }
                    if (len == MessageProClient.FRAME_LENGTH)
                    {
                        switch (len)
                        {
                            case 1:
                                int tmpBFrameLen = (int)bFrameLen[0];
                                iFrameLen = tmpBFrameLen;
                                break;
                            case 2:
                                short tmpSFrameLen = BitConverter.ToInt16(bFrameLen, 0);
                                iFrameLen = (int)IPAddress.NetworkToHostOrder(tmpSFrameLen);
                                break;
                            case 4:
                                int tmpFrameLen = BitConverter.ToInt32(bFrameLen, 0);
                                iFrameLen = IPAddress.NetworkToHostOrder(tmpFrameLen);
                                break;
                            default:
                                break;
                        }
                    }
                    int contentLen = 0;
                    byte[] tmpRecvBuf = new byte[1];
                    len = 0;
                    while (contentLen < iFrameLen)
                    {
                        len = sckClient.Receive(tmpRecvBuf, 1, SocketFlags.None);
                        if (len < 1)
                        {
                            if (sckClient != null && sckClient.Connected)
                            {
                                //Logger.LogInfo(strmthd, "Server【" + sEndPoint + "】失去连接，主动断开连接");
                                sckClient.Close();
                            }
                            return;
                        }

                        contentBuffer[contentLen] = tmpRecvBuf[0];
                        contentLen++;

                        if (contentLen == iFrameLen)
                        {
                            isFinished = true;
                        }
                    }

                }

                if (isFinished == true)
                {
                    byte[] realContent = new byte[iFrameLen];
                    Array.Copy(contentBuffer, 0, realContent, 0, iFrameLen);
                    MessageProClient.Instance.ReceiveEntireMessage(realContent);
                }
            }
            catch (Exception ex)
            {
                //Logger.LogError("JsonAccessClientReceiveTask", "【MessageClient】： Receive from server error : " + ex.Message);
            }
        }

        public override int CleanTask()
        {
            return 0;
        }

        public override void TaskExecutedWatch(Stopwatch watch)
        {

        }

        public override String GetTaskName()
        {
            return this.taskName;
        }

        public override void SetTaskName(string _taskName)
        {
            this.taskName = _taskName;
        }
        ////////////////////////////////////////End Of Class/////////////////////////////////////////////
    }
}
